/*****************************************************************************/
/*                                                                           */
/*                                exprdefs.c                                 */
/*                                                                           */
/*                        Expression tree definitions                        */
/*                                                                           */
/*                                                                           */
/*                                                                           */
/* (C) 1998-2012, Ullrich von Bassewitz                                      */
/*                Roemerstrasse 52                                           */
/*                D-70794 Filderstadt                                        */
/* EMail:         uz@cc65.org                                                */
/*                                                                           */
/*                                                                           */
/* This software is provided 'as-is', without any expressed or implied       */
/* warranty.  In no event will the authors be held liable for any damages    */
/* arising from the use of this software.                                    */
/*                                                                           */
/* Permission is granted to anyone to use this software for any purpose,     */
/* including commercial applications, and to alter it and redistribute it    */
/* freely, subject to the following restrictions:                            */
/*                                                                           */
/* 1. The origin of this software must not be misrepresented; you must not   */
/*    claim that you wrote the original software. If you use this software   */
/*    in a product, an acknowledgment in the product documentation would be  */
/*    appreciated but is not required.                                       */
/* 2. Altered source versions must be plainly marked as such, and must not   */
/*    be misrepresented as being the original software.                      */
/* 3. This notice may not be removed or altered from any source              */
/*    distribution.                                                          */
/*                                                                           */
/*****************************************************************************/

#include <stdio.h>

#include "abend.h"
#include "exprdefs.h"

/*****************************************************************************/
/*                                   Code                                    */
/*****************************************************************************/

static void InternalDumpExpr(const ExprNode *Expr, const ExprNode *(*ResolveSym)(const struct SymEntry *))
/* Dump an expression in RPN to stdout */
{
  if (Expr == 0) {
    return;
  }
  InternalDumpExpr(Expr->Left, ResolveSym);
  InternalDumpExpr(Expr->Right, ResolveSym);

  switch (Expr->Op) {

  case EXPR_LITERAL:
  case EXPR_ULABEL:
    printf(" $%04lX", Expr->V.IVal);
    break;

  case EXPR_SYMBOL:
    printf(" SYM(");
    if (ResolveSym && (Expr = ResolveSym(Expr->V.Sym)) != 0) {
      InternalDumpExpr(Expr, ResolveSym);
    }
    printf(") ");
    break;

  case EXPR_SECTION:
    printf(" SEC");
    break;

  case EXPR_SEGMENT:
    printf(" SEG");
    break;

  case EXPR_MEMAREA:
    printf(" MEM");
    break;

  case EXPR_PLUS:
    printf(" +");
    break;

  case EXPR_MINUS:
    printf(" -");
    break;

  case EXPR_MUL:
    printf(" *");
    break;

  case EXPR_DIV:
    printf(" /");
    break;

  case EXPR_MOD:
    printf(" MOD");
    break;

  case EXPR_OR:
    printf(" OR");
    break;

  case EXPR_XOR:
    printf(" XOR");
    break;

  case EXPR_AND:
    printf(" AND");
    break;

  case EXPR_SHL:
    printf(" SHL");
    break;

  case EXPR_SHR:
    printf(" SHR");
    break;

  case EXPR_EQ:
    printf(" =");
    break;

  case EXPR_NE:
    printf("<>");
    break;

  case EXPR_LT:
    printf(" <");
    break;

  case EXPR_GT:
    printf(" >");
    break;

  case EXPR_LE:
    printf(" <=");
    break;

  case EXPR_GE:
    printf(" >=");
    break;

  case EXPR_BOOLAND:
    printf(" BOOL_AND");
    break;

  case EXPR_BOOLOR:
    printf(" BOOL_OR");
    break;

  case EXPR_BOOLXOR:
    printf(" BOOL_XOR");
    break;

  case EXPR_MAX:
    printf(" MAX");
    break;

  case EXPR_MIN:
    printf(" MIN");
    break;

  case EXPR_UNARY_MINUS:
    printf(" NEG");
    break;

  case EXPR_NOT:
    printf(" ~");
    break;

  case EXPR_SWAP:
    printf(" SWAP");
    break;

  case EXPR_BOOLNOT:
    printf(" BOOL_NOT");
    break;

  case EXPR_BANK:
    printf(" BANK");
    break;

  case EXPR_BYTE0:
    printf(" BYTE0");
    break;

  case EXPR_BYTE1:
    printf(" BYTE1");
    break;

  case EXPR_BYTE2:
    printf(" BYTE2");
    break;

  case EXPR_BYTE3:
    printf(" BYTE3");
    break;

  case EXPR_WORD0:
    printf(" WORD0");
    break;

  case EXPR_WORD1:
    printf(" WORD1");
    break;

  case EXPR_FARADDR:
    printf(" FARADDR");
    break;

  case EXPR_DWORD:
    printf(" DWORD");
    break;

  case EXPR_NEARADDR:
    printf(" NEARADDR");
    break;

  default:
    AbEnd("Unknown Op type: %u", Expr->Op);
  }
}

void DumpExpr(const ExprNode *Expr, const ExprNode *(*ResolveSym)(const struct SymEntry *))
/* Dump an expression tree to stdout */
{
  InternalDumpExpr(Expr, ResolveSym);
  printf("\n");
}
